package com.geek.water.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.geek.water.entity.Bill;
import com.geek.water.entity.BillDetail;
import com.geek.water.exception.WaterException;
import com.geek.water.vo.BillQueryVO;
import com.geek.water.vo.BillVO;
import com.geek.water.vo.PageQueryVO;
import com.geek.water.vo.BillDetailVO;

import java.util.List;

public interface BillService extends IService<Bill> {

    /** 分页查询账单 */
    Page<BillVO> listBills(PageQueryVO queryVO, BillQueryVO billQueryVO);

    /** 带校验的删除 */
    boolean deleteBillWithCheck(Long billId);

    /** 手动删除账单 */
    boolean deleteBillManually(Long billId) throws WaterException;

    /** 批量删除账单 */
    boolean deleteBillsBatch(List<Long> billIds) throws WaterException;

    /** 更新账单状态 */
    void updateBillStatus(Long billId, String status) throws WaterException;

    /**
     * 创建新账单
     * @param billVO 前端传入的账单数据
     * @return 新生成的账单 VO（含 ID、时间等）
     */
    BillVO createBill(BillVO billVO) throws WaterException;

    /**
     * 通过账单编号查询账单
     * @param billCode 账单编号
     * @return 账单信息
     */
    Bill findByBillCode(String billCode);

    /**
     * 根据设备抄表数据生成账单
     * @param customerId 客户ID
     * @param billingPeriod 计费周期(格式: yyyy-MM)
     * @return 生成的账单
     */
    Bill generateBillFromDeviceReadings(Long customerId, String billingPeriod) throws WaterException;

    /**
     * 计算设备用水量和费用
     * @param deviceId 设备ID
     * @param billingPeriod 计费周期
     * @return 用水量和费用信息
     */
    BillDetail calculateDeviceUsage(Long deviceId, String billingPeriod) throws WaterException;

    /**
     * 获取客户的所有设备计费信息
     * @param customerId 客户ID
     * @param billingPeriod 计费周期
     * @return 设备计费信息列表
     */
    List<BillDetail> getCustomerDeviceBilling(Long customerId, String billingPeriod);

    /**
     * 检查客户在指定计费周期是否已存在账单
     * @param customerId 客户ID
     * @param billingPeriod 计费周期
     * @return 如果存在返回true，否则返回false
     */
    boolean existsBillByCustomerAndPeriod(Long customerId, String billingPeriod);

    /**
     * 根据账单ID获取账单详情
     * @param billId 账单ID
     * @return 账单详情信息
     */
    BillDetailVO getBillDetailById(Long billId);

    /**
     * 根据账单编号获取账单详情
     * @param billCode 账单编号
     * @return 账单详情信息
     */
    BillDetailVO getBillDetailByCode(String billCode);
}
